package com.hyts.dbutils.extense;

import com.hyts.dbutils.bean.dbutils.DbConnectionBean;
import com.hyts.dbutils.bean.dbutils.DbParameterBean;
import com.hyts.dbutils.common.DBUtilsPreparation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * project-name:coffice-toolbox
 * package-name:com.hyts.dbopera.dbutils
 * author:Libo/Alex
 * create-date:2019-06-24 20:59
 * copyright:libo-hyts-github
 * email:libo2dev@aliyun.com
 * description:此类主要用于:DBUtils工具类执行器服务
 */
public class DBUtilsRunner<P,R> implements DBUtilsPreparation {

    /**
     * 数据库链接对象
     */
    private DbConnectionBean dbConnBean;

    /**
     * 是否开启链接
     */
    private final boolean shouldBeOpen;

    /**
     * 构造器服务
     * @param dbConnBean
     */
    public DBUtilsRunner(DbConnectionBean dbConnBean) {
        shouldBeOpen = dbConnBean.getDataSource() == null;
        this.dbConnBean = build(dbConnBean);
    }

    /**
     * 执行操作调用
     * @param bean
     * @return
     */
    public boolean execute(DbParameterBean bean){
        //获取构建queryRunner
        QueryRunner queryRunner = (QueryRunner)dbConnBean.getQueryRunner();
        try {
            if(shouldBeOpen){
                Connection connection = openConnection(dbConnBean);
                connection.setAutoCommit(bean.isAutoClose());
                return rebool(queryRunner.execute(connection,bean.getSql(),bean.getParams()));
            }
            return rebool(queryRunner.execute(bean.getSql(),bean.isAutoClose(),bean.getParams()));
        } catch (SQLException e) {
            throw new IllegalArgumentException("执行sql语句失败!",e);
        }
    }

    /**
     * 执行操作调用
     * @param bean
     * @param returnType
     * @param <T>
     * @return
     */
    public <T> T execute(DbParameterBean bean, Class<T> returnType){
        //获取构建queryRunner
        QueryRunner queryRunner = (QueryRunner)dbConnBean.getQueryRunner();
        try {
            if(shouldBeOpen){
                Connection connection = openConnection(dbConnBean);
                connection.setAutoCommit(bean.isAutoClose());
                List<T> resultBean = queryRunner.execute(connection,bean.getSql(),new BeanHandler<>(returnType),bean.getParams());
                return getSingleBean(resultBean,returnType);
            }
            List<T> resultBean = queryRunner.execute(bean.getSql(),new BeanHandler<>(returnType),bean.getParams());
            return getSingleBean(resultBean,returnType);
        } catch (SQLException e) {
            throw new IllegalArgumentException("执行sql语句失败!",e);
        }
    }

    /**
     * 转换返回boolean类型数据
     * @return
     */
    private boolean rebool(int count){
        return count>0;
    }

    /**
     * 构造返回单支对象
     * @param resultBean
     * @param <T>
     * @return
     */
    private <T> T getSingleBean(List<T> resultBean,Class<T> returnType){
        if(CollectionUtils.isEmpty(resultBean)){
            return null;
        }
        return resultBean.get(0);
    }

}
